Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


nomadnet/vendor/Scrollable.py f8c57e675e6f7aa9a811c65d21fbe873f42736b0 (f8c57e67) Text, 22.38 KB

T8b949e# This program is free software: you can redistribute it and/or modify
T8b949e# it under the terms of the GNU General Public License as published by
T8b949e# the Free Software Foundation, either version 3 of the License, or
T8b949e# (at your option) any later version.
T8b949e#
T8b949e# This program is distributed in the hope that it will be useful
T8b949e# but WITHOUT ANY WARRANTY; without even the implied warranty of
T8b949e# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
T8b949e# GNU General Public License for more details
T8b949e# http://www.gnu.org/licenses/gpl-3.0.txt

Tff7b72import T7ee787time
Tff7b72import T7ee787urwid
Tff7b72from T7ee787urwidT7ee787.T7ee787widget Tff7b72import Te6edf3BOXTb4b4b4, Te6edf3FIXEDTb4b4b4, Te6edf3FLOW
Tff7b72from T7ee787collections Tff7b72import Te6edf3deque

T8b949e# Scroll actions
Te6edf3SCROLL_LINE_UP Tff7b72= Ta5d6ff'Ta5d6ffline upTa5d6ff'
Te6edf3SCROLL_LINE_DOWN Tff7b72= Ta5d6ff'Ta5d6ffline downTa5d6ff'
Te6edf3SCROLL_PAGE_UP Tff7b72= Ta5d6ff'Ta5d6ffpage upTa5d6ff'
Te6edf3SCROLL_PAGE_DOWN Tff7b72= Ta5d6ff'Ta5d6ffpage downTa5d6ff'
Te6edf3SCROLL_TO_TOP Tff7b72= Ta5d6ff'Ta5d6ffto topTa5d6ff'
Te6edf3SCROLL_TO_END Tff7b72= Ta5d6ff'Ta5d6ffto endTa5d6ff'

T8b949e# Scrollbar positions
Te6edf3SCROLLBAR_LEFT Tff7b72= Ta5d6ff'Ta5d6ffleftTa5d6ff'
Te6edf3SCROLLBAR_RIGHT Tff7b72= Ta5d6ff'Ta5d6ffrightTa5d6ff'

Tff7b72class T56d364ScrollableTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWidgetDecorationTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffsizingTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657frozensetTb4b4b4(Tb4b4b4[Te6edf3BOXTb4b4b4,Tb4b4b4]Tb4b4b4)

Tff7b72def Td2a8ffselectableTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3widgetTb4b4b4, Te6edf3force_forward_keypress Tff7b72= Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e"""Box widget that makes a fixed or flow widget vertically scrollable

TODO: Focusable widgets are handled, including switching focus, but
possibly not intuitively, depending on the arrangement of widgets. When
switching focus to a widget that is ouside of the visible part of the
original widget, the canvas scrolls up/down to the focused widget. It
would be better to scroll until the next focusable widget is in sight
first. But for that to work we must somehow obtain a list of focusable
rows in the original canvas.
"""
Tff7b72if Tff7b72not Tffa657anyTb4b4b4(Te6edf3s Tff7b72in Te6edf3widgetTff7b72.Td2a8ffsizingTb4b4b4(Tb4b4b4) Tff7b72for Te6edf3s Tff7b72in Tb4b4b4(Te6edf3FIXEDTb4b4b4, Te6edf3FLOWTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff'Ta5d6ffNot a fixed or flow widget: Tffd700%rTa5d6ff' Tff7b72% Te6edf3widgetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_old_cursor_coords Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_rows_max_cached Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffforce_forward_keypress Tff7b72= Te6edf3force_forward_keypress
Tff7b72selfTff7b72.Td2a8ffforce_cursor_update Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffanchor_cursor_update Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffcursor_update_forced_at Tff7b72= T79c0ff0
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Te6edf3widgetTb4b4b4)

Tff7b72def Td2a8ffrenderTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3focusTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3maxcolTb4b4b4, Te6edf3maxrow Tff7b72= Te6edf3size

T8b949e# Render complete original widget
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3ow_size Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_original_widget_sizeTb4b4b4(Te6edf3sizeTb4b4b4)
Te6edf3canv_full Tff7b72= Te6edf3owTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)

T8b949e# Make full canvas editable
Te6edf3canv Tff7b72= Te6edf3urwidTff7b72.Td2a8ffCompositeCanvasTb4b4b4(Te6edf3canv_fullTb4b4b4)
Te6edf3canv_colsTb4b4b4, Te6edf3canv_rows Tff7b72= Te6edf3canvTff7b72.Td2a8ffcolsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3canvTff7b72.Td2a8ffrowsTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3canv_cols Tff7b72<Tff7b72= Te6edf3maxcolTb4b4b4:
Te6edf3pad_width Tff7b72= Te6edf3maxcol Tff7b72- Te6edf3canv_cols
Tff7b72if Te6edf3pad_width Tff7b72> T79c0ff0Tb4b4b4:
T8b949e# Canvas is narrower than available horizontal space
Te6edf3canvTff7b72.Td2a8ffpad_trim_left_rightTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3pad_widthTb4b4b4)

Tff7b72if Te6edf3canv_rows Tff7b72<Tff7b72= Te6edf3maxrowTb4b4b4:
Te6edf3fill_height Tff7b72= Te6edf3maxrow Tff7b72- Te6edf3canv_rows
Tff7b72if Te6edf3fill_height Tff7b72> T79c0ff0Tb4b4b4:
T8b949e# Canvas is lower than available vertical space
Te6edf3canvTff7b72.Td2a8ffpad_trim_top_bottomTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3fill_heightTb4b4b4)

Tff7b72if Te6edf3canv_cols Tff7b72<Tff7b72= Te6edf3maxcol Tff7b72and Te6edf3canv_rows Tff7b72<Tff7b72= Te6edf3maxrowTb4b4b4:
T8b949e# Canvas is small enough to fit without trimming
Tff7b72return Te6edf3canv

Tff7b72selfTff7b72.Td2a8ff_adjust_trim_topTb4b4b4(Te6edf3canvTb4b4b4, Te6edf3sizeTb4b4b4)

T8b949e# Trim canvas if necessary
Te6edf3trim_top Tff7b72= Tff7b72selfTff7b72.Td2a8ff_trim_top
Te6edf3trim_end Tff7b72= Te6edf3canv_rows Tff7b72- Te6edf3maxrow Tff7b72- Te6edf3trim_top
Te6edf3trim_right Tff7b72= Te6edf3canv_cols Tff7b72- Te6edf3maxcol
Tff7b72if Te6edf3trim_top Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3canvTff7b72.Td2a8fftrimTb4b4b4(Te6edf3trim_topTb4b4b4)
Tff7b72if Te6edf3trim_end Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3canvTff7b72.Td2a8fftrim_endTb4b4b4(Te6edf3trim_endTb4b4b4)
Tff7b72if Te6edf3trim_right Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3canvTff7b72.Td2a8ffpad_trim_left_rightTb4b4b4(T79c0ff0Tb4b4b4, Tff7b72-Te6edf3trim_rightTb4b4b4)

T8b949e# Disable cursor display if cursor is outside of visible canvas parts
Tff7b72if Te6edf3canvTff7b72.Td2a8ffcursor Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3curscolTb4b4b4, Te6edf3cursrow Tff7b72= Te6edf3canvTff7b72.Td2a8ffcursor
Tff7b72if Te6edf3cursrow Tff7b72>Tff7b72= Te6edf3maxrow Tff7b72or Te6edf3cursrow Tff7b72< T79c0ff0Tb4b4b4:
Te6edf3canvTff7b72.Td2a8ffcursor Tff7b72= Tff7b72None

T8b949e# Figure out whether we should forward keypresses to original widget
Tff7b72if Te6edf3canvTff7b72.Td2a8ffcursor Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
T8b949e# Trimmed canvas contains the cursor, e.g. in an Edit widget
Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Te6edf3force_check Tff7b72= Tff7b72selfTff7b72.Td2a8ffforce_cursor_update Tff7b72and Tb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72selfTff7b72.Td2a8ffcursor_update_forced_at Tff7b72< T79c0ff0.25Tb4b4b4)
Te6edf3force_check Tff7b72|Tff7b72= Tff7b72selfTff7b72.Td2a8ffanchor_cursor_update
Tff7b72if Te6edf3canv_fullTff7b72.Td2a8ffcursor Tff7b72is Tff7b72not Tff7b72None Tff7b72or Te6edf3force_checkTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffforce_cursor_update Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ffanchor_cursor_update Tff7b72= Tff7b72False
T8b949e# Full canvas contains the cursor, but scrolled out of view
Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72= Tff7b72False
T8b949e# Reset cursor position on page/up down scrolling
Tff7b72tryTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3owTb4b4b4, Ta5d6ff"Ta5d6ffautomove_cursor_on_scrollTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3owTff7b72.Td2a8ffautomove_cursor_on_scrollTb4b4b4:
Te6edf3pwi Tff7b72= T79c0ff0
Te6edf3ch Tff7b72= T79c0ff0
Te6edf3last_hidden Tff7b72= Tff7b72False
Te6edf3first_visible Tff7b72= Tff7b72False
Tff7b72for Te6edf3wTb4b4b4,Te6edf3o Tff7b72in Te6edf3owTff7b72.Td2a8ffcontentsTb4b4b4:
Te6edf3wcanv Tff7b72= Te6edf3wTff7b72.Td2a8ffrenderTb4b4b4(Tb4b4b4(Te6edf3maxcolTb4b4b4,Tb4b4b4)Tb4b4b4)
Te6edf3wh Tff7b72= Te6edf3wcanvTff7b72.Td2a8ffrowsTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3whTb4b4b4:
Te6edf3ch Tff7b72+Tff7b72= Te6edf3wh

Tff7b72if Tff7b72not Te6edf3last_hidden Tff7b72and Te6edf3ch Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ff_trim_topTb4b4b4:
Te6edf3last_hidden Tff7b72= Tff7b72True

Tff7b72elif Te6edf3last_hiddenTb4b4b4:
Tff7b72if Tff7b72not Te6edf3first_visibleTb4b4b4:
Te6edf3first_visible Tff7b72= Tff7b72True

Tff7b72if Te6edf3wTff7b72.Td2a8ffselectableTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3owTff7b72.Td2a8fffocus_item Tff7b72= Te6edf3pwi

Te6edf3st Tff7b72= Tff7b72None
Te6edf3nf Tff7b72= Te6edf3owTff7b72.Td2a8ffget_focusTb4b4b4(Tb4b4b4)
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3nfTb4b4b4, Ta5d6ff"Ta5d6ffkey_timeoutTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3st Tff7b72= Te6edf3nf
Tff7b72elif Tffa657hasattrTb4b4b4(Te6edf3nfTb4b4b4, Ta5d6ff"Ta5d6fforiginal_widgetTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3no Tff7b72= Te6edf3nfTff7b72.Td2a8fforiginal_widget
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3noTb4b4b4, Ta5d6ff"Ta5d6fforiginal_widgetTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3st Tff7b72= Te6edf3noTff7b72.Td2a8fforiginal_widget
Tff7b72elseTb4b4b4:
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3noTb4b4b4, Ta5d6ff"Ta5d6ffkey_timeoutTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3st Tff7b72= Te6edf3no
Tff7b72if Te6edf3st Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3stTb4b4b4, Ta5d6ff"Ta5d6ffkey_timeoutTa5d6ff"Tb4b4b4) Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3stTb4b4b4, Ta5d6ff"Ta5d6ffkeypressTa5d6ff"Tb4b4b4) Tff7b72and Tffa657callableTb4b4b4(Te6edf3stTff7b72.Td2a8ffkeypressTb4b4b4)Tb4b4b4:
Te6edf3stTff7b72.Td2a8ffkeypressTb4b4b4(Tff7b72NoneTb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72break

Te6edf3pwi Tff7b72+Tff7b72= T79c0ff1
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tff7b72pass

Tff7b72elseTb4b4b4:
T8b949e# Original widget does not have a cursor, but may be selectable

T8b949e# FIXME: Using ow.selectable() is bad because the original
T8b949e# widget may be selectable because it's a container widget with
T8b949e# a key-grabbing widget that is scrolled out of view.
T8b949e# ow.selectable() returns True anyway because it doesn't know
T8b949e# how we trimmed our canvas.
T8b949e#
T8b949e# To fix this, we need to resolve ow.focus and somehow
T8b949e# ask canv whether it contains bits of the focused widget. I
T8b949e# can't see a way to do that.
Tff7b72if Te6edf3owTff7b72.Td2a8ffselectableTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72= Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72= Tff7b72False

Tff7b72return Te6edf3canv

Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
T8b949e# Maybe offer key to original widget
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_forward_keypress Tff7b72or Tff7b72selfTff7b72.Td2a8ffforce_forward_keypressTb4b4b4:
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3ow_size Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_original_widget_sizeTb4b4b4(Te6edf3sizeTb4b4b4)

T8b949e# Remember previous cursor position if possible
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3owTb4b4b4, Ta5d6ff'Ta5d6ffget_cursor_coordsTa5d6ff'Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_old_cursor_coords Tff7b72= Te6edf3owTff7b72.Td2a8ffget_cursor_coordsTb4b4b4(Te6edf3ow_sizeTb4b4b4)

Te6edf3key Tff7b72= Te6edf3owTff7b72.Td2a8ffkeypressTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3keyTb4b4b4)
Tff7b72if Te6edf3key Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Tff7b72None

T8b949e# Handle up/down, page up/down, etc
Te6edf3command_map Tff7b72= Tff7b72selfTff7b72.Td2a8ff_command_map
Tff7b72if Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_UPTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_LINE_UP
Tff7b72elif Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_DOWNTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_LINE_DOWN

Tff7b72elif Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_PAGE_UPTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_PAGE_UP
Tff7b72elif Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_PAGE_DOWNTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_PAGE_DOWN

Tff7b72elif Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_MAX_LEFTTb4b4b4: T8b949e# 'home'
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_TO_TOP
Tff7b72elif Te6edf3command_mapTb4b4b4[Te6edf3keyTb4b4b4] Tff7b72== Te6edf3urwidTff7b72.Td2a8ffCURSOR_MAX_RIGHTTb4b4b4: T8b949e# 'end'
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Te6edf3SCROLL_TO_END

Tff7b72elseTb4b4b4:
Tff7b72return Te6edf3key

Tff7b72selfTff7b72.Td2a8ff_invalidateTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffmouse_eventTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3colTb4b4b4, Te6edf3rowTb4b4b4, Te6edf3focusTb4b4b4)Tb4b4b4:
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3owTb4b4b4, Ta5d6ff'Ta5d6ffmouse_eventTa5d6ff'Tb4b4b4)Tb4b4b4:
Te6edf3ow_size Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_original_widget_sizeTb4b4b4(Te6edf3sizeTb4b4b4)
Te6edf3row Tff7b72+Tff7b72= Tff7b72selfTff7b72.Td2a8ff_trim_top
Tff7b72return Te6edf3owTff7b72.Td2a8ffmouse_eventTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3colTb4b4b4, Te6edf3rowTb4b4b4, Te6edf3focusTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72return Tff7b72False

Tff7b72def Td2a8ff_adjust_trim_topTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3canvTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4:
T8b949e"""Adjust self._trim_top according to self._scroll_action"""
Te6edf3action Tff7b72= Tff7b72selfTff7b72.Td2a8ff_scroll_action
Tff7b72selfTff7b72.Td2a8ff_scroll_action Tff7b72= Tff7b72None

Te6edf3maxcolTb4b4b4, Te6edf3maxrow Tff7b72= Te6edf3size
Te6edf3trim_top Tff7b72= Tff7b72selfTff7b72.Td2a8ff_trim_top
Te6edf3canv_rows Tff7b72= Te6edf3canvTff7b72.Td2a8ffrowsTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3trim_top Tff7b72< T79c0ff0Tb4b4b4:
T8b949e# Negative trim_top values use bottom of canvas as reference
Te6edf3trim_top Tff7b72= Te6edf3canv_rows Tff7b72- Te6edf3maxrow Tff7b72+ Te6edf3trim_top Tff7b72+ T79c0ff1

Tff7b72if Te6edf3canv_rows Tff7b72<Tff7b72= Te6edf3maxrowTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= T79c0ff0 T8b949e# Reset scroll position
Tff7b72return

Tff7b72def Td2a8ffensure_boundsTb4b4b4(Te6edf3new_trim_topTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Tffa657minTb4b4b4(Te6edf3canv_rows Tff7b72- Te6edf3maxrowTb4b4b4, Te6edf3new_trim_topTb4b4b4)Tb4b4b4)

Tff7b72if Te6edf3action Tff7b72== Te6edf3SCROLL_LINE_UPTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3ensure_boundsTb4b4b4(Te6edf3trim_top Tff7b72- T79c0ff1Tb4b4b4)
Tff7b72elif Te6edf3action Tff7b72== Te6edf3SCROLL_LINE_DOWNTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3ensure_boundsTb4b4b4(Te6edf3trim_top Tff7b72+ T79c0ff1Tb4b4b4)

Tff7b72elif Te6edf3action Tff7b72== Te6edf3SCROLL_PAGE_UPTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3ensure_boundsTb4b4b4(Te6edf3trim_top Tff7b72- Te6edf3maxrow Tff7b72+ T79c0ff1Tb4b4b4)
Tff7b72elif Te6edf3action Tff7b72== Te6edf3SCROLL_PAGE_DOWNTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3ensure_boundsTb4b4b4(Te6edf3trim_top Tff7b72+ Te6edf3maxrow Tff7b72- T79c0ff1Tb4b4b4)

Tff7b72elif Te6edf3action Tff7b72== Te6edf3SCROLL_TO_TOPTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= T79c0ff0
Tff7b72elif Te6edf3action Tff7b72== Te6edf3SCROLL_TO_ENDTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3canv_rows Tff7b72- Te6edf3maxrow

Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3ensure_boundsTb4b4b4(Te6edf3trim_topTb4b4b4)

T8b949e# If the cursor was moved by the most recent keypress, adjust trim_top
T8b949e# so that the new cursor position is within the displayed canvas part.
T8b949e# But don't do this if the cursor is at the top/bottom edge so we can still scroll out
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_old_cursor_coords Tff7b72is Tff7b72not Tff7b72None Tff7b72and Tff7b72selfTff7b72.Td2a8ff_old_cursor_coords Tff7b72!= Te6edf3canvTff7b72.Td2a8ffcursor Tff7b72and Te6edf3canvTff7b72.Td2a8ffcursor Tff7b72!= Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_old_cursor_coords Tff7b72= Tff7b72None
Te6edf3curscolTb4b4b4, Te6edf3cursrow Tff7b72= Te6edf3canvTff7b72.Td2a8ffcursor
Tff7b72if Te6edf3cursrow Tff7b72< Tff7b72selfTff7b72.Td2a8ff_trim_topTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Te6edf3cursrow
Tff7b72elif Te6edf3cursrow Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72+ Te6edf3maxrowTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3cursrow Tff7b72- Te6edf3maxrow Tff7b72+ T79c0ff1Tb4b4b4)

Tff7b72def Td2a8ff_get_original_widget_sizeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4)Tb4b4b4:
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3sizing Tff7b72= Te6edf3owTff7b72.Td2a8ffsizingTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3FLOW Tff7b72in Te6edf3sizingTb4b4b4:
Tff7b72return Tb4b4b4(Te6edf3sizeTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4,Tb4b4b4)
Tff7b72elif Te6edf3FIXED Tff7b72in Te6edf3sizingTb4b4b4:
Tff7b72return Tb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffget_scrollposTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTff7b72=Tff7b72NoneTb4b4b4, Te6edf3focusTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e"""Current scrolling position

Lower limit is 0, upper limit is the maximum number of rows with the
given maxcol minus maxrow.

NOTE: The returned value may be too low or too high if the position has
changed but the widget wasn't rendered yet.
"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_trim_top

Tff7b72def Td2a8ffset_scrollposTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3positionTb4b4b4)Tb4b4b4:
T8b949e"""Set scrolling position

If `position` is positive it is interpreted as lines from the top.
If `position` is negative it is interpreted as lines from the bottom.

Values that are too high or too low values are automatically adjusted
during rendering.
"""
Tff7b72selfTff7b72.Td2a8ff_trim_top Tff7b72= Tffa657intTb4b4b4(Te6edf3positionTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_invalidateTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrows_maxTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTff7b72=Tff7b72NoneTb4b4b4, Te6edf3focusTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
T8b949e"""Return the number of rows for `size`

If `size` is not given, the currently rendered number of rows is returned.
"""
Tff7b72if Te6edf3size Tff7b72is Tff7b72not Tff7b72NoneTb4b4b4:
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3ow_size Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_original_widget_sizeTb4b4b4(Te6edf3sizeTb4b4b4)
Te6edf3sizing Tff7b72= Te6edf3owTff7b72.Td2a8ffsizingTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3FIXED Tff7b72in Te6edf3sizingTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_rows_max_cached Tff7b72= Te6edf3owTff7b72.Td2a8ffpackTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)Tb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72elif Te6edf3FLOW Tff7b72in Te6edf3sizingTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_rows_max_cached Tff7b72= Te6edf3owTff7b72.Td2a8ffrowsTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72raise Tf85149RuntimeErrorTb4b4b4(Ta5d6ff'Ta5d6ffNot a flow/box widget: Tffd700%rTa5d6ff' Tff7b72% Tff7b72selfTff7b72.Td2a8ff_original_widgetTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_rows_max_cached


Tff7b72class T56d364ScrollBarTb4b4b4(Te6edf3urwidTff7b72.Td2a8ffWidgetDecorationTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffsizingTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657frozensetTb4b4b4(Tb4b4b4(Te6edf3BOXTb4b4b4,Tb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffselectableTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3widgetTb4b4b4, Te6edf3thumb_charTff7b72=Ta5d6ffuTa5d6ff'Tffea00\u2588Ta5d6ff'Tb4b4b4, Te6edf3trough_charTff7b72=Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4,
Te6edf3sideTff7b72=Te6edf3SCROLLBAR_RIGHTTb4b4b4, Te6edf3widthTff7b72=T79c0ff1Tb4b4b4)Tb4b4b4:
T8b949e"""Box widget that adds a scrollbar to `widget`

`widget` must be a box widget with the following methods:
- `get_scrollpos` takes the arguments `size` and `focus` and returns
the index of the first visible row.
- `set_scrollpos` (optional; needed for mouse click support) takes the
index of the first visible row.
- `rows_max` takes `size` and `focus` and returns the total number of
rows `widget` can render.

`thumb_char` is the character used for the scrollbar handle.
`trough_char` is used for the space above and below the handle.
`side` must be 'left' or 'right'.
`width` specifies the number of columns the scrollbar uses.
"""
Tff7b72if Te6edf3BOX Tff7b72not Tff7b72in Te6edf3widgetTff7b72.Td2a8ffsizingTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff'Ta5d6ffNot a box widget: Tffd700%rTa5d6ff' Tff7b72% Te6edf3widgetTb4b4b4)
Tffa657superTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ff__init__Tb4b4b4(Te6edf3widgetTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_thumb_char Tff7b72= Te6edf3thumb_char
Tff7b72selfTff7b72.Td2a8ff_trough_char Tff7b72= Te6edf3trough_char
Tff7b72selfTff7b72.Td2a8ffscrollbar_side Tff7b72= Te6edf3side
Tff7b72selfTff7b72.Td2a8ffscrollbar_width Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3widthTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_original_widget_size Tff7b72= Tb4b4b4(T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_sb_visible Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_sb_col_start Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sb_col_end Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sb_thumb_height Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_sb_ow_rows_max Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sb_maxrow Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sb_dragging Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_sb_drag_offset Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_accel Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_sevt_interval Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sevt_start Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sfreq_deque Tff7b72= Te6edf3dequeTb4b4b4(Te6edf3maxlenTff7b72=T79c0ff5Tb4b4b4)

Tff7b72def Td2a8ffrenderTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3focusTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3maxcolTb4b4b4, Te6edf3maxrow Tff7b72= Te6edf3size

Te6edf3sb_width Tff7b72= Tff7b72selfTff7b72.Td2a8ff_scrollbar_width
Te6edf3ow_size Tff7b72= Tb4b4b4(Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3maxcol Tff7b72- Te6edf3sb_widthTb4b4b4)Tb4b4b4, Te6edf3maxrowTb4b4b4)
Te6edf3sb_width Tff7b72= Te6edf3maxcol Tff7b72- Te6edf3ow_sizeTb4b4b4[T79c0ff0Tb4b4b4]

Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3ow_base Tff7b72= Tff7b72selfTff7b72.Td2a8ffscrolling_base_widget
Te6edf3ow_rows_max Tff7b72= Te6edf3ow_baseTff7b72.Td2a8ffrows_maxTb4b4b4(Te6edf3sizeTb4b4b4, Te6edf3focusTb4b4b4)
Tff7b72if Te6edf3ow_rows_max Tff7b72<Tff7b72= Te6edf3maxrowTb4b4b4:
T8b949e# Canvas fits without scrolling - no scrollbar needed
Tff7b72selfTff7b72.Td2a8ff_original_widget_size Tff7b72= Te6edf3size
Tff7b72selfTff7b72.Td2a8ff_sb_visible Tff7b72= Tff7b72False
Tff7b72return Te6edf3owTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3sizeTb4b4b4, Te6edf3focusTb4b4b4)
Te6edf3ow_rows_max Tff7b72= Te6edf3ow_baseTff7b72.Td2a8ffrows_maxTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)

Te6edf3ow_canv Tff7b72= Te6edf3owTff7b72.Td2a8ffrenderTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_original_widget_size Tff7b72= Te6edf3ow_size

Te6edf3pos Tff7b72= Te6edf3ow_baseTff7b72.Td2a8ffget_scrollposTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3focusTb4b4b4)
Te6edf3posmax Tff7b72= Te6edf3ow_rows_max Tff7b72- Te6edf3maxrow

T8b949e# Thumb shrinks/grows according to the ratio of
T8b949e# <number of visible lines> / <number of total lines>
Te6edf3thumb_weight Tff7b72= Tffa657minTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3maxrow Tff7b72/ Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3ow_rows_maxTb4b4b4)Tb4b4b4)
Te6edf3thumb_height Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657roundTb4b4b4(Te6edf3thumb_weight Tff7b72* Te6edf3maxrowTb4b4b4)Tb4b4b4)

T8b949e# Thumb may only touch top/bottom if the first/last row is visible
Te6edf3top_weight Tff7b72= Tffa657floatTb4b4b4(Te6edf3posTb4b4b4) Tff7b72/ Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Te6edf3posmaxTb4b4b4)
Te6edf3top_height Tff7b72= Tffa657intTb4b4b4(Tb4b4b4(Te6edf3maxrow Tff7b72- Te6edf3thumb_heightTb4b4b4) Tff7b72* Te6edf3top_weightTb4b4b4)
Tff7b72if Te6edf3top_height Tff7b72== T79c0ff0 Tff7b72and Te6edf3top_weight Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3top_height Tff7b72= T79c0ff1

T8b949e# Bottom part is remaining space
Te6edf3bottom_height Tff7b72= Te6edf3maxrow Tff7b72- Te6edf3thumb_height Tff7b72- Te6edf3top_height
Tff7b72assert Te6edf3thumb_height Tff7b72+ Te6edf3top_height Tff7b72+ Te6edf3bottom_height Tff7b72== Te6edf3maxrow

T8b949e# Create scrollbar canvas
T8b949e# Creating SolidCanvases of correct height may result in "cviews do not
T8b949e# fill gaps in shard_tail!" or "cviews overflow gaps in shard_tail!"
T8b949e# exceptions. Stacking the same SolidCanvas is a workaround.
T8b949e# https://github.com/urwid/urwid/issues/226#issuecomment-437176837
Te6edf3top Tff7b72= Te6edf3urwidTff7b72.Td2a8ffSolidCanvasTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_trough_charTb4b4b4, Te6edf3sb_widthTb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3thumb Tff7b72= Te6edf3urwidTff7b72.Td2a8ffSolidCanvasTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_thumb_charTb4b4b4, Te6edf3sb_widthTb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3bottom Tff7b72= Te6edf3urwidTff7b72.Td2a8ffSolidCanvasTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_trough_charTb4b4b4, Te6edf3sb_widthTb4b4b4, T79c0ff1Tb4b4b4)
Te6edf3sb_canv Tff7b72= Te6edf3urwidTff7b72.Td2a8ffCanvasCombineTb4b4b4(
Tb4b4b4[Tb4b4b4(Te6edf3topTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4] Tff7b72* Te6edf3top_height Tff7b72+
Tb4b4b4[Tb4b4b4(Te6edf3thumbTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4] Tff7b72* Te6edf3thumb_height Tff7b72+
Tb4b4b4[Tb4b4b4(Te6edf3bottomTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4] Tff7b72* Te6edf3bottom_heightTb4b4b4,
Tb4b4b4)

Te6edf3combinelist Tff7b72= Tb4b4b4[Tb4b4b4(Te6edf3ow_canvTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72TrueTb4b4b4, Te6edf3ow_sizeTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4,
Tb4b4b4(Te6edf3sb_canvTb4b4b4, Tff7b72NoneTb4b4b4, Tff7b72FalseTb4b4b4, Te6edf3sb_widthTb4b4b4)Tb4b4b4]




Tff7b72selfTff7b72.Td2a8ff_sb_visible Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_sb_thumb_height Tff7b72= Te6edf3thumb_height
Tff7b72selfTff7b72.Td2a8ff_sb_ow_rows_max Tff7b72= Te6edf3ow_rows_max
Tff7b72selfTff7b72.Td2a8ff_sb_maxrow Tff7b72= Te6edf3maxrow
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_scrollbar_side Tff7b72!= Te6edf3SCROLLBAR_LEFTTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sb_col_start Tff7b72= Te6edf3ow_sizeTb4b4b4[T79c0ff0Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_sb_col_end Tff7b72= Te6edf3ow_sizeTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72+ Te6edf3sb_width
Tff7b72return Te6edf3urwidTff7b72.Td2a8ffCanvasJoinTb4b4b4(Te6edf3combinelistTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sb_col_start Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_sb_col_end Tff7b72= Te6edf3sb_width
Tff7b72return Te6edf3urwidTff7b72.Td2a8ffCanvasJoinTb4b4b4(Tffa657reversedTb4b4b4(Te6edf3combinelistTb4b4b4)Tb4b4b4)

Tf0883e@property
Tff7b72def Td2a8ffscrollbar_widthTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Columns the scrollbar uses"""
Tff7b72return Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_scrollbar_widthTb4b4b4)

Tf0883e@scrollbar_widthTff7b72.Td2a8ffsetter
Tff7b72def Td2a8ffscrollbar_widthTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3widthTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_scrollbar_width Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tffa657intTb4b4b4(Te6edf3widthTb4b4b4)Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_invalidateTb4b4b4(Tb4b4b4)

Tf0883e@property
Tff7b72def Td2a8ffscrollbar_sideTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Where to display the scrollbar; must be 'left' or 'right'"""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_scrollbar_side

Tf0883e@scrollbar_sideTff7b72.Td2a8ffsetter
Tff7b72def Td2a8ffscrollbar_sideTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sideTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3side Tff7b72not Tff7b72in Tb4b4b4(Te6edf3SCROLLBAR_LEFTTb4b4b4, Te6edf3SCROLLBAR_RIGHTTb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff'Ta5d6ffscrollbar_side must be Ta5d6ff"Ta5d6ffleftTa5d6ff"Ta5d6ff or Ta5d6ff"Ta5d6ffrightTa5d6ff"Ta5d6ff, not Tffd700%rTa5d6ff' Tff7b72% Te6edf3sideTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_scrollbar_side Tff7b72= Te6edf3side
Tff7b72selfTff7b72.Td2a8ff_invalidateTb4b4b4(Tb4b4b4)

Tf0883e@property
Tff7b72def Td2a8ffscrolling_base_widgetTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e"""Nearest `original_widget` that is compatible with the scrolling API"""
Tff7b72def Td2a8fforig_iterTb4b4b4(Te6edf3wTb4b4b4)Tb4b4b4:
Tff7b72while Tffa657hasattrTb4b4b4(Te6edf3wTb4b4b4, Ta5d6ff'Ta5d6fforiginal_widgetTa5d6ff'Tb4b4b4)Tb4b4b4:
Te6edf3w Tff7b72= Te6edf3wTff7b72.Td2a8fforiginal_widget
Tff7b72yield Te6edf3w
Tff7b72yield Te6edf3w

Tff7b72def Td2a8ffis_scrolling_widgetTb4b4b4(Te6edf3wTb4b4b4)Tb4b4b4:
Tff7b72return Tffa657hasattrTb4b4b4(Te6edf3wTb4b4b4, Ta5d6ff'Ta5d6ffget_scrollposTa5d6ff'Tb4b4b4) Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3wTb4b4b4, Ta5d6ff'Ta5d6ffrows_maxTa5d6ff'Tb4b4b4)

Tff7b72for Te6edf3w Tff7b72in Te6edf3orig_iterTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3is_scrolling_widgetTb4b4b4(Te6edf3wTb4b4b4)Tb4b4b4:
Tff7b72return Te6edf3w
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff'Ta5d6ffNot compatible to be wrapped by ScrollBar: Tffd700%rTa5d6ff' Tff7b72% Te6edf3wTb4b4b4)

Tff7b72def Td2a8ffkeypressTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3keyTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_original_widgetTff7b72.Td2a8ffkeypressTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_original_widget_sizeTb4b4b4, Te6edf3keyTb4b4b4)

Tff7b72def Td2a8ffmouse_eventTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3colTb4b4b4, Te6edf3rowTb4b4b4, Te6edf3focusTb4b4b4)Tb4b4b4:
Te6edf3ow Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget
Te6edf3ow_size Tff7b72= Tff7b72selfTff7b72.Td2a8ff_original_widget_size
Te6edf3ow_base Tff7b72= Tff7b72selfTff7b72.Td2a8ffscrolling_base_widget Tff7b72if Tffa657hasattrTb4b4b4(Tff7b72selfTb4b4b4, Ta5d6ff'Ta5d6ffscrolling_base_widgetTa5d6ff'Tb4b4b4) Tff7b72else Te6edf3ow
Te6edf3on_sb Tff7b72= Tb4b4b4(Tff7b72selfTff7b72.Td2a8ff_sb_visible
Tff7b72and Tff7b72selfTff7b72.Td2a8ff_sb_col_start Tff7b72<Tff7b72= Te6edf3col Tff7b72< Tff7b72selfTff7b72.Td2a8ff_sb_col_endTb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_sb_draggingTb4b4b4:
Tff7b72if Ta5d6ff'Ta5d6ffdragTa5d6ff' Tff7b72in Te6edf3eventTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_set_scrollpos_from_rowTb4b4b4(Te6edf3rowTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72if Ta5d6ff'Ta5d6ffreleaseTa5d6ff' Tff7b72in Te6edf3event Tff7b72or Ta5d6ff'Ta5d6ffpressTa5d6ff' Tff7b72in Te6edf3eventTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sb_dragging Tff7b72= Tff7b72False
Tff7b72if Ta5d6ff'Ta5d6ffreleaseTa5d6ff' Tff7b72in Te6edf3eventTb4b4b4:
Tff7b72return Tff7b72True

T8b949e# Begin a click/drag
Tff7b72if Te6edf3on_sb Tff7b72and Ta5d6ff'Ta5d6ffpressTa5d6ff' Tff7b72in Te6edf3event Tff7b72and Te6edf3button Tff7b72== T79c0ff1 Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3ow_baseTb4b4b4, Ta5d6ff'Ta5d6ffset_scrollposTa5d6ff'Tb4b4b4)Tb4b4b4:
Te6edf3pos Tff7b72= Te6edf3ow_baseTff7b72.Td2a8ffget_scrollposTb4b4b4(Te6edf3ow_sizeTb4b4b4)
Te6edf3posmax Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_sb_ow_rows_max Tff7b72- Tff7b72selfTff7b72.Td2a8ff_sb_maxrowTb4b4b4)
Te6edf3track_len Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_sb_maxrow Tff7b72- Tff7b72selfTff7b72.Td2a8ff_sb_thumb_heightTb4b4b4)
Te6edf3top_height Tff7b72= Tffa657intTb4b4b4(Tffa657roundTb4b4b4(Te6edf3track_len Tff7b72* Te6edf3pos Tff7b72/ Te6edf3posmaxTb4b4b4)Tb4b4b4)
Tff7b72if Te6edf3top_height Tff7b72<Tff7b72= Te6edf3row Tff7b72< Te6edf3top_height Tff7b72+ Tff7b72selfTff7b72.Td2a8ff_sb_thumb_heightTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_sb_drag_offset Tff7b72= Te6edf3row Tff7b72- Te6edf3top_height
Tff7b72elseTb4b4b4:
T8b949e# jump
Tff7b72selfTff7b72.Td2a8ff_sb_drag_offset Tff7b72= Tff7b72selfTff7b72.Td2a8ff_sb_thumb_height Tff7b72/Tff7b72/ T79c0ff2
Tff7b72selfTff7b72.Td2a8ff_set_scrollpos_from_rowTb4b4b4(Te6edf3rowTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_sb_dragging Tff7b72= Tff7b72True
Tff7b72return Tff7b72True

Te6edf3handled Tff7b72= Tff7b72False
Tff7b72if Tffa657hasattrTb4b4b4(Te6edf3owTb4b4b4, Ta5d6ff'Ta5d6ffmouse_eventTa5d6ff'Tb4b4b4)Tb4b4b4:
Te6edf3handled Tff7b72= Te6edf3owTff7b72.Td2a8ffmouse_eventTb4b4b4(Te6edf3ow_sizeTb4b4b4, Te6edf3eventTb4b4b4, Te6edf3buttonTb4b4b4, Te6edf3colTb4b4b4, Te6edf3rowTb4b4b4, Te6edf3focusTb4b4b4)

Tff7b72if Tff7b72not Te6edf3handled Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3owTb4b4b4, Ta5d6ff'Ta5d6ffset_scrollposTa5d6ff'Tb4b4b4)Tb4b4b4:
Te6edf3owTff7b72.Td2a8ffforce_cursor_update Tff7b72= Tff7b72True
Te6edf3owTff7b72.Td2a8ffcursor_update_forced_at Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_sevt_interval Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tff7b72-Tff7b72selfTff7b72.Td2a8ff_sevt_start
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_sevt_interval Tff7b72> T79c0ff0.3Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_sevt_start Tff7b72= T79c0ff0Tb4b4b4; Tff7b72selfTff7b72.Td2a8ff_accel Tff7b72= T79c0ff1Tb4b4b4; Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_sevt_start Tff7b72== T79c0ff0Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_sevt_start Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_sevt_interval Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3sevt_freq Tff7b72= T79c0ff1Tff7b72/Tff7b72selfTff7b72.Td2a8ff_sevt_interval
Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTff7b72.Td2a8ffappendTb4b4b4(Te6edf3sevt_freqTb4b4b4)
Te6edf3freq_smth Tff7b72= Tffa657sumTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTb4b4b4)Tff7b72/Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTb4b4b4) Tff7b72>Tff7b72= Tff7b72selfTff7b72.Td2a8ff_sfreq_dequeTff7b72.Td2a8ffmaxlenTb4b4b4:
Tff7b72if Te6edf3freq_smth Tff7b72> T79c0ff25.0Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_accel Tff7b72= Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_accelTb4b4b4, T79c0ff3Tb4b4b4)
Tff7b72elif Te6edf3freq_smth Tff7b72> T79c0ff12.0Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_accel Tff7b72= Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_accelTb4b4b4, T79c0ff2Tb4b4b4)
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ff_accel Tff7b72= Tffa657maxTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_accelTb4b4b4, T79c0ff1Tb4b4b4)
T8b949e# import RNS; RNS.log(f"a={self._accel} s={RNS.prettyfrequency(freq_smth)} f={RNS.prettyfrequency(sevt_freq)}", RNS.LOG_CRITICAL)
Te6edf3step Tff7b72= Tff7b72selfTff7b72.Td2a8ff_accel
Tff7b72if Te6edf3button Tff7b72== T79c0ff4Tb4b4b4: T8b949e# scroll wheel up
Te6edf3pos Tff7b72= Te6edf3owTff7b72.Td2a8ffget_scrollposTb4b4b4(Te6edf3ow_sizeTb4b4b4)
Te6edf3newpos Tff7b72= Te6edf3pos Tff7b72- Te6edf3step
Tff7b72if Te6edf3newpos Tff7b72< T79c0ff0Tb4b4b4: Te6edf3newpos Tff7b72= T79c0ff0
Te6edf3owTff7b72.Td2a8ffset_scrollposTb4b4b4(Te6edf3newposTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72elif Te6edf3button Tff7b72== T79c0ff5Tb4b4b4: T8b949e# scroll wheel down
Te6edf3pos Tff7b72= Te6edf3owTff7b72.Td2a8ffget_scrollposTb4b4b4(Te6edf3ow_sizeTb4b4b4)
Te6edf3owTff7b72.Td2a8ffset_scrollposTb4b4b4(Te6edf3pos Tff7b72+ Te6edf3stepTb4b4b4)
Tff7b72return Tff7b72True

Tff7b72return Tff7b72False

Tff7b72def Td2a8ff_set_scrollpos_from_rowTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3rowTb4b4b4)Tb4b4b4:
Te6edf3ow_base Tff7b72= Tff7b72selfTff7b72.Td2a8ffscrolling_base_widget
Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3ow_baseTb4b4b4, Ta5d6ff'Ta5d6ffset_scrollposTa5d6ff'Tb4b4b4)Tb4b4b4:
Tff7b72return
Te6edf3posmax Tff7b72= Tff7b72selfTff7b72.Td2a8ff_sb_ow_rows_max Tff7b72- Tff7b72selfTff7b72.Td2a8ff_sb_maxrow
Tff7b72if Te6edf3posmax Tff7b72<Tff7b72= T79c0ff0Tb4b4b4:
Tff7b72return
Te6edf3track_len Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_sb_maxrow Tff7b72- Tff7b72selfTff7b72.Td2a8ff_sb_thumb_heightTb4b4b4)
Te6edf3top Tff7b72= Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Tffa657minTb4b4b4(Te6edf3track_lenTb4b4b4, Te6edf3row Tff7b72- Tff7b72selfTff7b72.Td2a8ff_sb_drag_offsetTb4b4b4)Tb4b4b4)
Te6edf3new_pos Tff7b72= Tffa657intTb4b4b4(Tffa657roundTb4b4b4(Te6edf3top Tff7b72* Te6edf3posmax Tff7b72/ Te6edf3track_lenTb4b4b4)Tb4b4b4)
Te6edf3new_pos Tff7b72= Tffa657maxTb4b4b4(T79c0ff0Tb4b4b4, Tffa657minTb4b4b4(Te6edf3posmaxTb4b4b4, Te6edf3new_posTb4b4b4)Tb4b4b4)
Te6edf3ow_baseTff7b72.Td2a8ffset_scrollposTb4b4b4(Te6edf3new_posTb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────